package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@Service
public class MovementServiceImpl implements MovementService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;
    /**
     * 保存动态
     * 1.往动态详情添加一条数据(完整记录)
     * 2.往自己的动态表中添加一条记录(只有动态id)
     * 3.查询好友的关系
     * 4.往好友的朋友圈表中加入一条记录(动态id和userId 发布人id)
     */
    @Override
    public ObjectId saveMovement(Movement movement) {
        //1.往动态详情添加一条数据(完整记录)
        movement.setCreated(System.currentTimeMillis());
        movement.setPid(idService.getNextId(ConstantUtil.MOVEMENT_ID));//mongo使用自增id
        mongoTemplate.save(movement); //保存动态 mongo保存完数据 主键会自动返回
        ObjectId movementId = movement.getId();//自动返回的动态id


        //2.往自己的动态表中添加一条记录(只有动态id)
        MyMovement myMovement = new MyMovement();
        myMovement.setPublishId( movementId ); //动态的id
        myMovement.setCreated(System.currentTimeMillis());//时间
        mongoTemplate.save(myMovement , ConstantUtil.MOVEMENT_MINE + movement.getUserId());


        //3.查询好友的关系
        //封装条件  查询我的好友
        Query query = new Query(
                new Criteria().where("userId").is(movement.getUserId())
        );
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);

        //4.往好友的朋友圈表中加入一条记录(动态id和userId 发布人id)
        if(CollectionUtil.isNotEmpty(friendList)){//因为我新注册用户可能没有好友
            for (Friend friend : friendList) {
                // 好友的朋友圈
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setCreated(System.currentTimeMillis());
                friendMovement.setUserId(friend.getUserId());//发动态这个人的id
                friendMovement.setPublishId(movementId);//动态的id
                mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND + friend.getFriendId() );
            }
        }
        return  movementId;
    }

    /**
     * 查询个人动态
     * 1.根据用户的id先找个人动态表 将动态的id查询出来
     * 2.通过动态的id循环遍历获得数据
     * 4.查询总记录数
     * 3.返回PageBeanVo
     */
    @Override
    public PageBeanVo findMyMovement(Integer pageNumber, Integer pageSize, Long userId) {
        //1.根据用户的id先找个人动态表 将动态的id查询出来
        //计算开始索引
        int startIndex = (pageNumber-1)*pageSize;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))//时间降序
                .skip(startIndex).limit(pageSize); //分页数据
        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        //提前定义存储的动态集合数据
        List<Movement> list = new ArrayList<>();
        //2.通过动态的id循环遍历获得数据
        if(CollectionUtil.isNotEmpty(myMovementList)){
            for (MyMovement myMovement : myMovementList) {
                //动态详情对象
                Movement movement = mongoTemplate.findById(myMovement.getPublishId(), Movement.class);
                if(movement.getState() == 1){ //状态已审核的 才展示
                    list.add(movement);
                }
            }
        }
        //4.查询总记录数
        long counts = mongoTemplate.count(query, ConstantUtil.MOVEMENT_MINE + userId);
        //3.返回PageBeanVo
        return new PageBeanVo(pageNumber , pageSize , counts , list);
    }

    /**
     * 查询当前用户的好友动态数据
     * @param pageNumber
     * @param pageSize
     * @param userId
     * @return
     */
    @Override
    public PageBeanVo findFriendMovements(Integer pageNumber, Integer pageSize, Long userId) {
        //1.根据用户的id先找朋友圈表, 目的查询出 朋友圈动态  动态id值
        //计算开始索引
        int startIndex = (pageNumber-1)*pageSize;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))//时间降序
                .skip(startIndex).limit(pageSize); //分页数据
        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //提前定义存储的动态集合数据
        List<Movement> list = new ArrayList<>();
        //2.通过动态的id循环遍历获得数据
        if(CollectionUtil.isNotEmpty(friendMovementList)){
            for (FriendMovement friendMovement : friendMovementList) {
                //动态详情对象
                Movement movement = mongoTemplate.findById(friendMovement.getPublishId(), Movement.class);
                if(movement.getState() == 1){ //状态已审核的 才展示
                    list.add(movement);
                }
            }
        }
        //4.查询总记录数
        long counts = mongoTemplate.count(query, ConstantUtil.MOVEMENT_FRIEND + userId);
        //3.返回PageBeanVo
        return new PageBeanVo(pageNumber , pageSize , counts , list);
    }

    /**
     * 查询推荐
     * @param pageNumber
     * @param pageSize
     * @param id
     * @return
     */
    @Override
    public PageBeanVo findRecommendMovement(Integer pageNumber, Integer pageSize, Long id) {
        //1.查询推荐的动态id
        int startIndex=  (pageNumber-1)*pageSize;
        Query query  = new Query(
                new Criteria().where("userId").is(id)
        ).with(Sort.by(Sort.Order.desc("score")))
                .skip(startIndex).limit(pageSize);
        //查询
        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);

        List<Movement> movementList = new ArrayList<>();
        //2.根据查询的动态id  查询出动态表的详情信息
        if(CollectionUtil.isNotEmpty(recommendMovementList)){
            //2.1.构造一点假数据
            //2.2.自己往推荐动态添加数据
            for (RecommendMovement recommendMovement : recommendMovementList) {
                Movement movement = mongoTemplate.findById(recommendMovement.getPublishId(), Movement.class);
                if(movement.getState()==1){
                    movementList.add(movement);
                }
            }
        }
        //查询总记录数据
        long counts = mongoTemplate.count(query, RecommendMovement.class);
        return new PageBeanVo(pageNumber , pageSize , counts ,movementList );
    }

    /**
     * 根据动态id查询动态对象
     * @param movementId
     * @return
     */
    @Override
    public Movement findMovementById(String movementId) {
        Movement movement = mongoTemplate.findById(movementId, Movement.class);
        return movement;
    }

    /**
     * 分页查询动态数据
     * @param pageNumber
     * @param pageSize
     * @param uid
     * @param stateInt
     * @return
     */
    @Override
    public PageBeanVo findMovementsByUserIdAndState(Integer pageNumber, Integer pageSize, Long uid, Integer stateInt) {
        int startIndex  = (pageNumber-1)*pageSize;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip(startIndex).limit(pageSize);
        if(uid != null){//动态拼接条件
            query.addCriteria( Criteria.where("userId").is(uid));
        }
        if(stateInt != null){//动态拼接条件
            query.addCriteria( Criteria.where("state").is(stateInt));
        }
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);
        long count = mongoTemplate.count(query, Movement.class);
        return new PageBeanVo(pageNumber , pageSize , count ,movementList );
    }

    //修改动态
    @Override
    public void updateMovement(Movement movement) {
        mongoTemplate.save(movement);// 有就是修改 没有就是保存
    }
}
